package com.qwc.blog.controller.back;


import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qwc.blog.common.exception.BadRequestException;
import com.qwc.blog.common.utils.FileUtils;
import com.qwc.blog.config.QblogProperties;
import com.qwc.blog.entity.User;
import com.qwc.blog.entity.vo.user.*;
import com.qwc.blog.security.service.LoginService;
import com.qwc.blog.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static com.qwc.blog.common.constant.CommonConstant.SUPER_ADMIN;
import static com.qwc.blog.common.constant.ResponseConstant.*;

/**
 * <p>
 * 用户信息表 前端控制器
 * </p>
 *
 * @author qwc
 * @since 2021-10-15
 */
@RestController
@RequestMapping("/blog/user")
public class UserController {

    @Autowired
    private LoginService loginService;

    @Autowired
    private IUserService userService;

    @Autowired
    private QblogProperties qblogProperties;

    /**
     * 获取当前登录用户信息
     *
     * @return
     */
    @GetMapping("/info")
    public ResponseEntity<Object> getInfo() {
        Map<String, Object> map = new HashMap<>(4);
        User user = loginService.getCurrentUser();
        map.put(DATA, CurrentUserVo.createVo(user));
        return ResponseEntity.ok(map);
    }

    /**
     * 修改当前用户信息
     *
     * @param dto
     * @return
     */
    @PutMapping("/profile")
    public ResponseEntity<Object> putProfile(@Validated @RequestBody PutProfileDto dto) {
        User user = loginService.getCurrentUser();
        userService.updateProfile(user, dto);
        return ResponseEntity.ok().build();
    }

    /**
     * 修改当前用户信息密码
     *
     * @param dto
     * @return
     */
    @PutMapping("/update/password")
    public ResponseEntity<Object> updatePassword(@Validated @RequestBody UpdatePasswordDto dto) {
        User user = loginService.getCurrentUser();
        userService.updatePassword(user, dto);
        return ResponseEntity.ok().build();
    }

    /**
     * 上传头像
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/upload/avatar")
    public ResponseEntity<Object> uploadAvatar(@RequestParam("avatar") MultipartFile file) throws IOException {
        String avatar = FileUtils.upload(file, qblogProperties.getAvatarPath());
        Map<String, Object> map = new HashMap<>(4);
        User user = loginService.getCurrentUser();
        userService.updateAvatar(user, avatar);
        map.put(IMG_URL, avatar);
        return ResponseEntity.ok(map);
    }

    /**
     * 分页查询用户列表
     *
     * @param dto
     * @return
     */
    @GetMapping("/list")
    public ResponseEntity<Object> getUserList(UserListReqDto dto) {
        Map<String, Object> map = new HashMap<>(4);
        Page<User> page = userService.getUserList(dto);
        map.put(ROWS, page.getRecords());
        map.put(TOTAL, page.getTotal());
        return ResponseEntity.ok(map);
    }

    @PostMapping
    public ResponseEntity<Object> addUser(@Validated @RequestBody AddUserDto dto) {
        User user = loginService.getCurrentUser();
        userService.addUser(dto, user);
        return ResponseEntity.ok().build();
    }

    @PutMapping("/change/status")
    public ResponseEntity<Object> changeUserStatus(Integer userId, String status) {
        userService.update(Wrappers.<User>lambdaUpdate()
                .eq(User::getUserId, userId)
                .set(User::getStatus, status)
                .set(User::getUpdateBy, loginService.getCurrentUsername()));
        return ResponseEntity.ok().build();
    }

    @DeleteMapping("/{userId}")
    public ResponseEntity<Object> deleteUser(@PathVariable Integer[] userId) {
        checkSuperAdmin(userId);
        userService.removeByIds(Arrays.asList(userId));
        return ResponseEntity.ok().build();
    }

    @GetMapping("/{userId}")
    public ResponseEntity<Object> getUser(@PathVariable Integer userId) {
        Map<String, Object> map = new HashMap<>(4);
        User user = userService.getById(userId);
        map.put(DATA, user);
        return ResponseEntity.ok(map);
    }

    @PutMapping
    public ResponseEntity<Object> updateUser(@Validated @RequestBody UpdateUserDto dto) {
        User user = dto.createUser();
        user.setUpdateBy(loginService.getCurrentUsername());
        userService.updateUser(user);
        return ResponseEntity.ok().build();
    }

    @PostMapping("/reset/password")
    public ResponseEntity<Object> resetPassword(@Validated @RequestBody RestPasswordDto dto) {
        checkSuperSingleAdmin(dto.getUserId());
        User user = dto.createUser();
        user.setUpdateBy(loginService.getCurrentUsername());
        userService.resetPassword(user);
        return ResponseEntity.ok().build();
    }

    @PutMapping("/update/introduction")
    public ResponseEntity<Object> updateIntroduction(@Validated @RequestBody UpdateIntroductionDto dto) {
        User user = dto.createUser();
        user.setUpdateBy(loginService.getCurrentUsername());
        userService.updateById(user);
        return ResponseEntity.ok().build();
    }

    private void checkSuperAdmin(Integer[] userIds) {
        for (Integer userId : userIds) {
            checkSuperSingleAdmin(userId);
        }
    }

    private void checkSuperSingleAdmin(Integer userId) {
        if (SUPER_ADMIN.equals(userId)) {
            throw new BadRequestException(NOT_ALLOW_OPERATION);
        }
    }

}
